# autointel.R
# solution tree

source('autoplot.R')
source('autodist.R')
source('autoutils.R')

draw_progress <- function(ratio, x, y)
{
	xi <- max(x)-1
	xf <- max(x)
	posy <- max(y)
	rect(xi, posy, xf, posy * .9, col='lightgray')
	rect(xi, posy, xi+(ratio*(xf-xi)), posy * .9, col='blue')
}

##

STEP <- 5
incweight <- function(distrs, d)
	changeweight(distrs, d, .5)
meanleft <- function(distrs, d)
	movenorm(distrs, d, -STEP)
meanright <- function(distrs, d)
	movenorm(distrs, d, +STEP)
sdthin <- function(distrs, d)
	shapenorm(distrs, d, -STEP)
sdfat <- function(distrs, d)
	shapenorm(distrs, d, +STEP)

FUNCS <- list(meanleft, meanright, sdthin, sdfat, incweight)
TESTED <- list()

# tree leaf:
# (error, distrs)

cmp_leaf <- function(n1, n2)
	n1[[1]] - n2[[1]]

test_dist <- function(distr, x,y)
{
	TESTED[[length(TESTED)+1]] <<- distr

	ydist <- gendists(distr, x)
	e <- calcerror(y, ydist)
	list(e, distr)
}

expand <- function(distrs, x,y)
{
	filhos <- list()
	i <- 1
	for(d in 1:length(distrs))
		for(f in FUNCS) {
			ds <- f(distrs, d)
			if(!list_contains(TESTED, ds, is_distr)) {
				filhos[[i]] <- test_dist(ds, x,y)
				i <- i+1
			}
		}
	filhos
}

pause <- function() readline(prompt = 'Pause')

expand_root <- function(x, y)
{
	NDISTR <- 3
	root <- list()

	for(t1 in 0:2) {
		root[[length(root)+1]] <- test_dist(startfit(c(t1), x,y), x,y)
		if(NDISTR > 1)
			for(t2 in 0:2) {
				root[[length(root)+1]] <- test_dist(startfit(c(t1, t2), x,y), x,y)
				if(NDISTR > 2)
					for(t3 in 0:2)
						root[[length(root)+1]] <- test_dist(startfit(c(t1, t2, t3), x,y), x,y)
			}
	}
	root
}

histdados <- function(x,y)
	y / sum(y) / (x[2]-x[1])

intelifit <- function(x, y)
{
time <- unclass(Sys.time())
tested <- 0

	y <- histdados(x,y)

	raiz <- expand_root(x,y)
	melhor <- raiz[[1]]
	TESTED <<- list()

	melhores <- list()
	for(f in raiz) {
		melhores <- order_add(melhores, f, cmp_leaf)
		if(f[[1]] < melhor[[1]])
			melhor <- f
		tested <- tested+1
#print(f[[1]])
	}

	TEST <- 250
	iter <- 0
	while(iter < TEST && length(melhores) > 0) {
		topo <- melhores[[1]]
		melhores <- melhores[-1]
#print(topo)
#pause()

		filhos <- expand(topo[[2]], x,y)
		for(f in filhos) {
			melhores <- order_add(melhores, f, cmp_leaf)
			if(f[[1]] < melhor[[1]])
				melhor <- f
			tested <- tested+1
		}

		if((iter %% 5) == 0) {
			plotfit(x, y, topo[[2]])
			draw_progress(iter/TEST, x,y)
		}
		iter <- iter+1
	}

print('melhor:')
print(paste('erro:', melhor[[1]]))
print_distrs(melhor[[2]])
	plotfit(x, y, melhor[[2]])

print(paste(round((unclass(Sys.time()) - time)/60, 3), 'm'))
print(paste(tested, 'tested cases'))
	melhor
}

